#include<iostream>
#include<string.h>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#include"log.hpp"
using namespace std;

void *recverAndPrint(void *args)
{
    while (true)
    {
        int sockfd = *(int *)args;
        char buffer[1024];
        struct sockaddr_in temp;
        socklen_t len = sizeof(temp);
        ssize_t s = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&temp, &len);
        if (s > 0)
        {
            buffer[s] = 0;
            std::cout << "server echo# " << buffer << std::endl;
        }
    }
}

// ./udpclient ip port
int main(int argc,char* argv[])
{
    cout<<"pid:"<<getpid()<<endl;
    if(argc!=3)
    {
        exit(1);
    }
    //1、提取客户端要来连接的服务器的ip
    //client必须知道要连接的server对应的端口号和ip
    string server_ip=argv[1];
    uint16_t server_port=atoi(argv[2]);
    //2、创建客户端
    int socketfd = socket(AF_INET,SOCK_DGRAM,0);
    if (socketfd < 0)
    {
        LogMessage(FATAL, "socket:%s,%d", strerror(errno), socketfd);
        exit(1);
    }
    else
    {
        LogMessage(DEBUG, "socket create success:%d", socketfd);
    }
    //客户端不需要我们主动bind，os会帮我们绑定，os会随机分配port，第一次使用sendto函数会自动bind
    //3、发送数据
    struct sockaddr_in server;
    string buffer;
    bzero(&server,sizeof(server));
    server.sin_family=AF_INET;
    //主机转网络字节序，发送数据时端口号和ip也会发送过去
    server.sin_port=htons(server_port);
    //点分十进制转四字节
    server.sin_addr.s_addr=inet_addr(server_ip.c_str());
    pthread_t t;
    pthread_create(&t, nullptr, recverAndPrint, (void *)&socketfd);
    while (true)
    {
        cerr << "Please Enter: " << endl;
        getline(cin, buffer);
        //向服务器端发送数据
        sendto(socketfd, buffer.c_str(), buffer.size(), 0,(const struct sockaddr*)&server,sizeof(server));
    }
    return 0;
}